<?php

namespace app\beautiful\controller\admin\appointment;

use app\BaseController;

use app\beautiful\logic\printer\PrinterLogic;

use app\beautiful\model\appointment\AppointmentModel;

use app\beautiful\model\appointment\TechnicianModel;

use app\beautiful\model\appointment\TechnicianProjectModel;

use app\beautiful\model\appointment\TechnicianSchedulingModel;
use app\beautiful\model\member\MemberModel;

use app\beautiful\model\project\ProjectModel;

use app\beautiful\model\project\ProjectTypeModel;

use app\beautiful\model\setting\SettingSmsModel;

use app\common\logic\DataLogic;

use app\common\logic\SmsLogic;



class Appointment extends BaseController{

    protected $name='预约';



    public function index()

    {

        $appointment_id = $this->request->param('appointment_id/d',0);

        $technician=$this->request->param('technician');

        $member=$this->request->param('member');

        $appoint_time=$this->request->param('appoint_time/a',[]);

        $status=$this->request->param('status/d',0);

        $project_type_id=$this->request->param('project_type_id/d',0);



        $where=[

            ['shop_id','=',$this->request->shopId]

        ];

        if(!empty($appointment_id)) $where[]=['appointment_id','=',$appointment_id];



        if(!empty($technician)){

            $technician_where=[

                ['shop_id','=',$this->request->shopId],

                ['name|mobile','=',$technician]

            ];

            $technician_ids=TechnicianModel::where($technician_where)->column('technician_id') ?? [];

            $where[]=['technician_id','in',$technician_ids];

        }



        if(!empty($member)){

            $member_where=[

                ['shop_id','=',$this->request->shopId],

                ['nick_name|mobile','=',$member]

            ];

            $member_ids=MemberModel::where($member_where)->column('member_id') ?? [];

            $where[]=['member_id','in',$member_ids];

        }



        if(!empty($project_type_id)){

            $project_where=[

                ['shop_id','=',$this->request->shopId],

                ['project_type_id','=',$project_type_id],

            ];

            $project_ids=ProjectModel::where($project_where)->column('project_id') ?? [];

            $where[]=['project_id','in',$project_ids];

        }



        if(!empty($status)) $where[]=['status','=',$status];



        //预约时间判断

        if(!empty($appoint_time) && count($appoint_time) == 2){

            $appoint_bg_time=$appoint_time[0];

            $appoint_end_time=$appoint_time[1];

            if(!empty($appoint_bg_time) || !empty($appoint_end_time)){

                if(false !== $appoint_bg_time_unix = strtotime($appoint_bg_time." 00:00:00")){

                    if(false !== $appoint_end_time_unix = strtotime($appoint_end_time." 23:59:59")){

                        $where[]=['day','between',[$appoint_bg_time,$appoint_end_time]];

                    }else{

                        $where[]=['day','>=',$appoint_bg_time];

                    }

                }else{

                    if(false !== $appoint_end_time_unix = strtotime($appoint_end_time." 23:59:59")){

                        $where[]=['day','<=',$appoint_bg_time];

                    }

                }

            }

        }



        $appointment_model = new AppointmentModel();

        $appointment_model=$appointment_model->with(['member','technician']);

        $order=['add_time'=>'desc'];

        $field="*";

        $append=['add_time_format','status_means','operate_type_means','arrival_time_format','cancel_time_format'];

        $return = DataLogic::getDataList($appointment_model,$where,$order,$field,$this->request->limit,$this->request->page,$append);

        if($this->request->page==1){

            $type_list=ProjectTypeModel::where([

                ['shop_id','=',$this->request->shopId],

                ['is_delete','=',0]

            ])->field('project_type_id,name')->select()->toArray();

            $return['type_list']=$type_list;

        }

        //处理数据
        $lists = $return['list'];
        if(empty(!$lists)){

            $key_start = $this->request->limit * ($this->request->page - 1);
            $key_end = $return['total'];

            foreach ($lists as $k => $list){
                $lists[$k]['show_appointment_id']= $key_end - ($key_start + $k);
            }
        }
        $return['list']=$lists;

        return $this->success($return);

    }



    public function chooseProject()

    {

        $name= $this->request->param('name');

        $where=[

            ['shop_id','=',$this->request->shopId],

            ['is_delete','=',0],

        ];

        if(!empty($name)) $where[]=['abbreviation','=',$name];



        $project_model= new ProjectModel();

        $order=['add_time'=>'desc'];

        $field='*';

        $append=['add_time_format'];

        $return = DataLogic::getDataList($project_model,$where,$order,$field,$this->request->limit,$this->request->page,$append);

        return $this->success($return);

    }



    public function chooseTechnician()

    {

        $name=$this->request->param('name');

        $appointment_id=$this->request->param('appointment_id');

        $search=$this->request->param('search');

        $where=[

            ['shop_id','=',$this->request->shopId],

            ['status','=',1],

            ['is_delete','=',0]

        ];
        

        if(!empty($name)) $where[]=['name','=',$name];
        
        
        //指派技师时搜索
        if(!empty($search)) $where[]=['name|mobile','like','%'.$search.'%'];
        //根据预约分配技师
        if(!empty($appointment_id)){

            //用户预约
            if(null === $appointment_info=AppointmentModel::find($appointment_id))  return $this->error('预约不存在');
            /*判断技师是否有排版开始
                     $start_totime=strtotime($appointment_info->day.' '.$appointment_info->start_time);

                     $end_totime=strtotime($appointment_info->day.' '.$appointment_info->end_time);

                     $start_time=(int)str_replace(':','',$appointment_info->start_time);

                     $end_time=(int)str_replace(':','',$appointment_info->end_time);

                     //技师排班
                     $technician_arr=TechnicianSchedulingModel::withCount(['appointment'=>function($query){

                         $query->where([

                             ['shop_id','=',$this->request->shopId],

                             ['status','in',[1,4,8]]

                         ]);

                     }])->where("day='{$appointment_info->day}' and CONVERT(REPLACE(start_time,':',''),SIGNED) <= '{$start_time}' and CONVERT(REPLACE(end_time,':',''),SIGNED)>={$end_time}")

                         ->where(['project_id'=>$appointment_info->project_id])

                         ->select()

                         ->toArray();

                    $technician_id_arr=[];

                    foreach ($technician_arr as $k=>$v){
                        if($v['appointment_count'] >= $v['appointment_num']){
                            $technician_id_arr[]=$v['technician_id'];
                        }
                    }

                    $where[] = ['technician_id', 'in', implode(',',$technician_id_arr)];

                     判断技师是否有排版结束*/


            //技师排班
            $technician_arr=TechnicianSchedulingModel::withCount(['appointment'=>function($query){

                $query->where([

                    ['shop_id','=',$this->request->shopId],

                    ['status','in',[1,4,8]]

                ]);

            }])->where("day='{$appointment_info->day}' and start_time= '{$appointment_info->start_time}' and end_time='{$appointment_info->end_time}'")

                ->where(['project_id'=>$appointment_info->project_id])

                ->select()

                ->toArray();

            $technician_id_arr=[];

            foreach ($technician_arr as $k=>$v){
                if($v['appointment_count'] >= $v['appointment_num']){
                    $technician_id_arr[]=$v['technician_id'];
                }
            }

            $where[] = ['technician_id', 'not in', implode(',',$technician_id_arr)];

        }

        
        $technician_model= new TechnicianModel();

        if(!empty($appointment_id))   $technician_model = $technician_model->with(['schedulings']);

        $order=['add_time'=>'desc'];$field="*";$append=['add_time_format'];

        $limit=$this->request->limit;$page=$this->request->page;

        $return = DataLogic::getDataList($technician_model,$where,$order,$field,$limit,$page,$append);

        if(!empty($appointment_id)){

            foreach ($return['list'] as $key=>$vlaue){

                foreach ($vlaue['schedulings'] as $k=>$v){
                    //显示符合条件的排班
//                    if(strtotime($v['day'].' '.$v['start_time'])<=$start_totime && $end_totime<=strtotime($v['day'].' '.$v['end_time'])){
//
//                        $return['list'][$key]['schedulings']=$v;
//                    }
                    if($v['day']==$appointment_info->day){
                        $schedulings[]=$v;

                    }
                }
                unset($return['list'][$key]['schedulings']);
                $return['list'][$key]['schedulings'] = isset($schedulings)?$schedulings:'';
            }
        }

        return $this->success($return);

    }



    public function save()

    {

        $today=date("Y-m-d",$this->request->time());

        $member_id=$this->request->param('member_id/d',0);

        $project_id=$this->request->param('project_id/d',0);

        $technician_id=$this->request->param('technician_id/d',0);

        $day=$this->request->param('day');

        $appoint_time=$this->request->param('appoint_time/a',[]);



        if($member_id==0) return $this->error('请选择用户');

        if($project_id==0) return $this->error('请选择服务项目');

        if(empty($day)) return $this->error('请选择预约日期');

        if(false === strtotime($day.' 00.00.00')) return $this->error('请选择预约日期');

        if($day<$today) return $this->error('预约日期不能低于今天');

        if(empty($appoint_time) || !is_array($appoint_time) ||count($appoint_time)!=2) return $this->error('请选择预约时间');

        $start_time=$appoint_time[0];$end_time=$appoint_time[1];

        if(false === $start_time_unix=strtotime($day.' '.$start_time.':00')) return $this->error('请选择预约开始时间');

        if($start_time_unix<=$this->request->time()) return $this->error('预约开始时间低于当前时间');

        if(false === $end_time_unix=strtotime($day.' '.$end_time.':00')) return $this->error('请选择预约结束时间');

        $interval=$end_time_unix-$start_time_unix;

        if($interval<=0) return $this->error('预约开始时间不能大于结束时间');

        if($interval%1800!=0)return $this->error('预约时间间隔必须是30分钟的整倍');



        if(null === $member = MemberModel::find($member_id)) return $this->error('用户不存在，请重新选择');

        if($member->shop_id != $this->request->shopId) return $this->error('用户不存在，请重新选择');

        if($member->is_delete != 0) return $this->error('用户不存在，请重新选择');



        if(null === $project = ProjectModel::find($project_id)) return $this->error('项目不存在，请重新选择');

        if($project->shop_id != $this->request->shopId) return $this->error('项目不存在，请重新选择');

        if($project->is_delete != 0) return $this->error('项目不存在，请重新选择');



        if($technician_id!=0){

            if(null === $technician = TechnicianModel::find($technician_id)) return $this->error('技师不存在，请重新选择');

            if($technician->shop_id != $this->request->shopId) return $this->error('技师不存在，请重新选择');

            if($technician->status != 1) return $this->error('技师已离职，请重新选择');

            if($technician->is_delete != 0) return $this->error('技师不存在，请重新选择');

        }



        $appointment_model=new AppointmentModel();

        $appointment_model->shop_id=$this->request->shopId;

        $appointment_model->member_id=$member_id;

        $appointment_model->member_name=$member->nick_name;

        $appointment_model->member_mobile=$member->mobile;

        $appointment_model->project_id=$project_id;

        $appointment_model->project_name=$project->abbreviation;

        $appointment_model->project_cover_img=$project->cover_img;

        $appointment_model->technician_id=$technician_id;

        if($technician_id!=0){

            $appointment_model->technician_name=$technician->name;

            $appointment_model->technician_mobile=$technician->mobile;

        }



        $appointment_model->day=$day;

        $appointment_model->start_time=$start_time;

        $appointment_model->end_time=$end_time;

        $appointment_model->save();





        try{

            //发送短信给用户

            $sms_setting = SettingSmsModel::where([['shop_id','=',$this->request->shopId]])->find();

            if(null !== $sms_setting){

                if($sms_setting->appointment_notice_member==1){

                    $sms_logic= new SmsLogic();

                    $params=[

                        'xm'=>$project->abbreviation,

                        't'=>$start_time.'-'.$end_time

                    ];

                    $sms_logic->send($this->request->shopId,[$member->mobile],$params,'appointmentNoticeMember');

                }



                //发送短信给服务人员

                if($technician_id !=0 ){

                    if($sms_setting->appointment_notice_service_person==1){

                        $sms_logic= new SmsLogic();

                        $params=[

                            'mobile'=>$member->mobile,

                            'xm'=>$project->abbreviation,

                            't'=>$start_time.'-'.$end_time

                        ];

                        $sms_logic->send($this->request->shopId,[$technician->mobile],$params,'appointmentNoticeServicePerson');

                    }

                }

            }





        }catch (\Exception $e){



        }



//        //打印机

//        $printer_logic =new PrinterLogic($this->request->shopId);

//        $printer_logic->print('appointment',$appointment_model->appointment_id);



        return $this->success('操作成功');

    }



    public function sure()

    {

        $appointment_id=$this->request->param('appointment_id/d',0);

        if($appointment_id==0) return $this->error($this->name.'不存在');

        if(null == $appointment = AppointmentModel::find($appointment_id)) return $this->error($this->name.'不存在');

        if($appointment->shop_id != $this->request->shopId) return $this->error($this->name.'不存在');

        if($appointment->status !=1) return $this->error($this->name.'不在状态');

        $appoint_time=strtotime($appointment->day.' '.$appointment->end_time.':00');

        if($appoint_time<$this->request->time()) return $this->error('预约时间已过');



        $appointment->status=4;

        $appointment->save();



        //发送短信给用户

        try{

            $sms_setting = SettingSmsModel::where([['shop_id','=',$this->request->shopId]])->find();

            if(null !== $sms_setting){

                if($sms_setting->sure_appointment==1){

                    $sms_logic= new SmsLogic();

                    $params=[

                        'xm'=>$appointment->project_name,

                        't'=>$appointment->start_time.'-'.$appointment->end_time

                    ];

                    $sms_logic->send($this->request->shopId,[$appointment->member_mobile],$params,'sureAppointment');

                }

            }

        }catch (\Exception $e){



        }

        return $this->success('确认预约成功');

    }



    public function cancel()

    {

        $appointment_id=$this->request->param('appointment_id/d',0);

        $reason=$this->request->param('reason');



        if($appointment_id==0) return $this->error($this->name.'不存在');



        if(null == $appointment = AppointmentModel::find($appointment_id)) return $this->error($this->name.'不存在');

        if($appointment->shop_id != $this->request->shopId) return $this->error($this->name.'不存在');

        if(!in_array($appointment->status,[1,4])) return $this->error($this->name.'不在状态');



        $appointment->status=-1;

        $appointment->cancel_time=$this->request->time();

        $appointment->reason=$reason;

        $appointment->operate_type=2;

        $appointment->operate_id=$this->request->accountId;

        $appointment->operate_name=$this->request->account->username;

        $appointment->operate_mobile=$this->request->account->mobile;

        $appointment->save();



        //发送短信给用户

        try{

            $sms_setting = SettingSmsModel::where([['shop_id','=',$this->request->shopId]])->find();

            if(null !== $sms_setting){

                if($sms_setting->cancel_appointment==1){

                    $sms_logic= new SmsLogic();

                    $params=[

                        'xm'=>$appointment->project_name,

                    ];

                    $sms_logic->send($this->request->shopId,[$appointment->member_mobile],$params,'cancelAppointment');

                }

            }

        }catch (\Exception $e){



        }

        return $this->success('取消预约成功');

    }



    public function arrival()

    {

        $appointment_id=$this->request->param('appointment_id/d',0);

        if($appointment_id==0) return $this->error($this->name.'不存在');

        if(null == $appointment = AppointmentModel::find($appointment_id)) return $this->error($this->name.'不存在');

        if($appointment->shop_id != $this->request->shopId) return $this->error($this->name.'不存在');

        if($appointment->status !=4) return $this->error($this->name.'不在状态');



        $appointment->status=8;

        $appointment->arrival_time=$this->request->time();

        $appointment->operate_type=2;

        $appointment->operate_id=$this->request->accountId;

        $appointment->operate_name=$this->request->account->username;

        $appointment->operate_mobile=$this->request->account->mobile;

        $appointment->save();



        if(null !== $technician_project = TechnicianProjectModel::where([

                ['shop_id','=',$this->request->shopId],

                ['technician_id','=',$appointment->technician_id],

                ['project_id','=',$appointment->project_id],

                ['is_delete','=',0]

            ])->find()){

            $technician_project->engaged_num=$technician_project->engaged_num + 1;

            $technician_project->save();

        }

        return $this->success('取消预约成功');

    }

    /**
     *指派技师
     */
    public function appointTechnician(){
        $appointment_id = $this->request->param('appointment_id/d',0);
        $technician_id = $this->request->param('technician_id/d',0);
        $scheduling_id = $this->request->param('scheduling_id/d',0);

        if($appointment_id==0 || $technician_id==0) return $this->error('参数有误');
        //判断预约
        if(null === $appointment_info = AppointmentModel::find($appointment_id)) return $this->error('参数有误');

        if($appointment_info->technician_id) return $this->error('已分配技师');

        //判断项目

        if(null === $project = ProjectModel::find($appointment_info->project_id)) return $this->error('服务项目不存在');

        if($project->shop_id != $this->request->shopId) return $this->error('服务项目不存在');

        if($project->is_delete != 0) return $this->error('服务项目不存在');

        //判断技师

        if(null === $technician = TechnicianModel::find($technician_id)) return $this->error('技师不存在');

        if($technician->shop_id != $this->request->shopId) return $this->error('技师不存在');

        if($technician->is_delete != 0) return $this->error('技师不存在');



        //判断技师的排班
        if($scheduling_id>0){

            if($scheduling_id==0) return $this->error('请选择时间');

            if(null === $scheduling = TechnicianSchedulingModel::find($scheduling_id)) return $this->error('请选择时间');

            if($scheduling->shop_id != $this->request->shopId) return $this->error('请选择时间');

            if($scheduling->is_delete != 0) return $this->error('请选择时间');

            if($scheduling->technician_id != $technician_id) return $this->error('请选择时间');

            if($scheduling->day != $appointment_info->day) return $this->error('请选择时间');

            if($scheduling->project_id != $appointment_info->project_id) return $this->error('请选择时间');


            //判断技师排班的数量有没有超过

            $scheduling_num=AppointmentModel::where([

                    ['shop_id','=',$this->request->shopId],

                    ['scheduling_id','=',$scheduling_id],

                    ['status','in',[1,4,8]]

                ])->count() ?? 0;



            $appointment_num=$scheduling->appointment_num ==0 ? $this->setting->appointment_num : $scheduling->appointment_num;

            if($scheduling_num>=$appointment_num) return $this->error('该时间段预约已经满了，请重新选择');

        }

        $update_appointment_info['technician_id']=$technician_id;

        $update_appointment_info['scheduling_id']=$scheduling_id;

        $update_appointment_info['technician_name']=$technician->name;

        $update_appointment_info['technician_mobile']=$technician->mobile;


        AppointmentModel::where(['appointment_id'=>$appointment_id])->update($update_appointment_info);

        $start_time=$appointment_info->start_time;

        $end_time=$appointment_info->end_time;

        try{

            //发送短信给用户

            $sms_setting = SettingSmsModel::where([['shop_id','=',$this->request->shopId]])->find();

            if(null !== $sms_setting){

                if($sms_setting->appointment_notice_member==1){

                    $sms_logic= new SmsLogic();

                    $params=[

                        'xm'=>$project->abbreviation,

                        't'=>$start_time.'-'.$end_time

                    ];

                    $sms_logic->send($this->request->shopId,[$this->request->member->mobile],$params,'appointmentNoticeMember');

                }



                //发送短信给服务人员

                if($technician_id !=0 ){

                    if($sms_setting->appointment_notice_service_person==1){

                        $sms_logic= new SmsLogic();

                        $params=[

                            'mobile'=>$this->request->member->mobile,

                            'xm'=>$project->abbreviation,

                            't'=>$start_time.'-'.$end_time

                        ];

                        $sms_logic->send($this->request->shopId,[$technician->mobile],$params,'appointmentNoticeServicePerson');

                    }

                }



                //发送给管理员

                if($sms_setting->appointment_notice_admin==1 && !empty($sms_setting->boss_mobiles)){

                    $sms_logic= new SmsLogic();

                    $params=[

                        'mobile'=>$this->request->member->mobile,

                        'xm'=>$project->abbreviation,

                        't'=>$start_time.'-'.$end_time

                    ];

                    $sms_logic->send($this->request->shopId,$sms_setting->boss_mobiles,$params,'appointmentNoticeAdmin');

                }

            }





        }catch (\Exception $e){



        }



        //打印机

        $printer_logic =new PrinterLogic($this->request->shopId);

        $printer_logic->print('appointment',$appointment_id);

        return $this->success('指派成功');


    }

}

